package com.ity.teamanagement.config;

import com.fasterxml.classmate.TypeResolver;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.data.domain.Pageable;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.AlternateTypeRule;
import springfox.documentation.schema.AlternateTypeRuleConvention;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;

import static com.google.common.collect.Lists.newArrayList;
import static springfox.documentation.schema.AlternateTypeRules.newRule;

/**
 * @author coderFu
 * @create 2021/5/23
 */
@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Bean
    public Docket api(){
        //参数构造器
        ParameterBuilder tokenValue = new ParameterBuilder();
        List<Parameter> pars = new ArrayList<>();
        //header中的token参数非必填，传空也可以
        tokenValue.name("Set-Cookie").description("用户令牌")
                .modelRef(new ModelRef("String")).parameterType("header")
                .required(false).build();
        //根据每个方法名也知道当前方法在设置设什么参数
        pars.add(tokenValue.build());

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                //配置扫描的包路径
                .apis(RequestHandlerSelectors.basePackage("com.ity.teamanagement.controller"))
                .paths(PathSelectors.any())
                .build()
                .globalOperationParameters(pars);
    }

    private ApiInfo apiInfo(){
        return new ApiInfoBuilder()
                .title("cloud-tea")
                .description("茶树种质管理")
                .version("1.0")
                .build();
    }

    //使得Pageable的参数可在swagger填写配置
    @Bean
    public AlternateTypeRuleConvention pageableConvention(final TypeResolver resolver) {
        return new AlternateTypeRuleConvention() {
            @Override
            public int getOrder() {
                return Ordered.HIGHEST_PRECEDENCE;
            }

            @Override
            public List<AlternateTypeRule> rules() {
                return newArrayList(newRule(resolver.resolve(Pageable.class), resolver.resolve(Page.class)));
            }
        };
    }

    @ApiModel
    @Data
    static class Page {
        @ApiModelProperty(value = "要检索的结果页（0..N）", example = "0")
        private Integer page;

        @ApiModelProperty(value = "每页记录数", example = "10")
        private Integer size;

        @ApiModelProperty(value = "排序条件的格式为：property（，asc | desc）。默认排序顺序为升序。支持多种排序条件。")
        private List<String> sort;
    }
}
